/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.icee.myth.server.contsign;

import com.icee.myth.config.MapConfig;
import com.icee.myth.log.GameLogger;
import com.icee.myth.log.message.FileDebugGameLogMessage;
import com.icee.myth.log.message.GameLogMessage;
import com.icee.myth.log.message.builder.GameLogMessageBuilder;
import com.icee.myth.protobuf.ExternalCommonProtocol.ContSignProto;
import com.icee.myth.protobuf.InternalCommonProtocol.DBContSignProto;
import com.icee.myth.protobuf.builder.ClientToMapBuilder;
import com.icee.myth.server.GameServer;
import com.icee.myth.server.actor.Human;
import com.icee.myth.server.reward.CertainRewardInfo;
import com.icee.myth.utils.Consts;

import java.util.ArrayList;
import java.util.List;

/**
 * 签到计数器
 * @author yangyi
 */
public class ContSign {
    public Human human;
    public int lastOnlineDay ; //最后一天登录时间

    // 累计签到
    public int cumulativeNum;   // 累计天数
    public int cumulativeRewardNum;  // 可领取的奖励天数（客户端发领取时，一次性领取所有）

    // 连续签到
    public int consecutiveNum;  // 连续天数
    public int consecutiveReceiveFlag;  //连续登陆奖励是否领取标志（位值0表示未领取）
    public int livenessReceiveFlag;     //活跃奖励是否领取标志（位值0表示未领取）
    public Liveness liveness;
    
    public ContSign(Human human, DBContSignProto dBContSignProto){
        this.human = human;
        
        if(dBContSignProto != null){
            lastOnlineDay = dBContSignProto.getLastOnlineDay();
            
            cumulativeNum = dBContSignProto.getCumulativeNum();
            cumulativeRewardNum = dBContSignProto.getCumulativeRewardNum();
            
            consecutiveNum = dBContSignProto.getConsecutiveNum();
            consecutiveReceiveFlag = dBContSignProto.getConsecutiveReceiveFlag();
            
            livenessReceiveFlag = dBContSignProto.getLivenessReceiveFlag();
            liveness = new Liveness(human, dBContSignProto.getLivenessTarget());
        } else {
            lastOnlineDay = (int) ((GameServer.INSTANCE.getCurrentTime() + Consts.JET_LAG) / Consts.MILSECOND_ONE_DAY);

            cumulativeNum = 1;
            cumulativeRewardNum = 1;

            consecutiveNum = 1;
            consecutiveReceiveFlag = 0;

            livenessReceiveFlag = 0;
            liveness = new Liveness(human);
        }
    }

    public DBContSignProto buildDBContSignProto(){
        DBContSignProto.Builder builder = DBContSignProto.newBuilder();

        builder.setLastOnlineDay(lastOnlineDay);

        builder.setCumulativeNum(cumulativeNum);
        builder.setCumulativeRewardNum(cumulativeRewardNum);

        builder.setConsecutiveNum(consecutiveNum);
        builder.setConsecutiveReceiveFlag(consecutiveReceiveFlag);

        builder.setLivenessReceiveFlag(livenessReceiveFlag);
        builder.setLivenessTarget(liveness.target.buildProto());
        
        return builder.build();
    }

    public ContSignProto buildContSignProto(){
        ContSignProto.Builder builder = ContSignProto.newBuilder();

        builder.setCumulativeNum(cumulativeNum);
        builder.setCumulativeRewardNum(cumulativeRewardNum);

        builder.setConsecutiveNum(consecutiveNum);
        builder.setConsecutiveReceiveFlag(consecutiveReceiveFlag);

        builder.setLiveness(liveness.liveness);
        builder.setLivenessReceiveFlag(livenessReceiveFlag);
        builder.setLivenessTarget(liveness.target.buildProto());
        return builder.build();
    }

    public void receiveCumulativeSignReward() {
        if (cumulativeRewardNum > 0) {
            for (int i = cumulativeRewardNum-1; i>=0; i--) {
                int rewardId = cumulativeNum - i - 1;
                CertainRewardInfo certainRewardInfo = ContSignTemplates.INSTANCE.cumulativeRewards[rewardId];

                human.digestCertainReward(certainRewardInfo, Consts.SOUL_CHANGE_LOG_TYPE_CUMULATIVE_SIGN_REWARD, rewardId);
            }

            // 记录行为日志
            if (MapConfig.INSTANCE.useCYLog == true) {
                List<String> cyLogList = new ArrayList<String>();
                cyLogList.add("behaviorMC");
                cyLogList.add(String.valueOf(MapConfig.INSTANCE.gameId));
                cyLogList.add("KDTY");
                cyLogList.add(String.valueOf(human.id));
                cyLogList.add(human.name);
                cyLogList.add("");
                cyLogList.add("CumulativeSignRewardDBBehavior");
                cyLogList.add(cumulativeNum + " " + cumulativeRewardNum);
                cyLogList.add("");
                cyLogList.add("");
                cyLogList.add("");
                cyLogList.add("");
                cyLogList.add("");
                GameLogger.getlogger().log(GameLogMessageBuilder.buildFileCYGameLogMessage(cyLogList, GameLogMessage.GameLogType.GAMELOGTYPE_CY_BEHAVIOR));
            }

            GameLogger.getlogger().log(GameLogMessageBuilder.buildCumulativeSignRewardDBBehaviorGameLogMessage(human.id, cumulativeNum, cumulativeRewardNum));

            cumulativeRewardNum = 0;

            human.sendMessage(ClientToMapBuilder.buildCumulativeRewardReceived());
        } else {
             GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                    "human [" + human.id + "] can't receive cumulative sign reward because no reward."));
        }
    }

    public void receiveConsecutiveSignReward(int day){
        if(day >= 0 && day < consecutiveNum){
            if ((~consecutiveReceiveFlag & (1 << day)) != 0) {  // 判断领取标志位
                CertainRewardInfo certainRewardInfo = ContSignTemplates.INSTANCE.consecutiveRewards[day];
                human.digestCertainReward(certainRewardInfo, Consts.SOUL_CHANGE_LOG_TYPE_CONSECUTIVE_SIGN_REWARD, day);

                // 设置领取标志位
                consecutiveReceiveFlag |= 1 << day;

                human.sendMessage(ClientToMapBuilder.buildReceivedConsecutiveSignReward(day));

                // 记录行为日志
              if (MapConfig.INSTANCE.useCYLog == true) {
                List<String> cyLogList = new ArrayList<String>();
                cyLogList.add("behaviorMC");
                cyLogList.add(String.valueOf(MapConfig.INSTANCE.gameId));
                cyLogList.add("KDTY");
                cyLogList.add(String.valueOf(human.id));
                cyLogList.add(human.name);
                cyLogList.add("");
                cyLogList.add("ConsecutiveSignRewardDBBehavior");
                cyLogList.add(day + " ");
                cyLogList.add("");
                cyLogList.add("");
                cyLogList.add("");
                cyLogList.add("");
                cyLogList.add("");
                GameLogger.getlogger().log(GameLogMessageBuilder.buildFileCYGameLogMessage(cyLogList, GameLogMessage.GameLogType.GAMELOGTYPE_CY_BEHAVIOR));
            }

                GameLogger.getlogger().log(GameLogMessageBuilder.buildConsecutiveSignRewardDBBehaviorGameLogMessage(human.id, day));
            } else {
                 GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                        FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                        "human [" + human.id + "] can't receive sign reward because of has received or not cont sign"));
            }
        }else {
             GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                    "human [" + human.id + "] can't receive sign reward because of day outof array bounds"));
        }
    }

    public void receiveLivenessReward(int index){
        if(index >= 0 && index < ContSignTemplates.INSTANCE.livenessRewards.length ){
            LivenessRewardTemplate template = ContSignTemplates.INSTANCE.livenessRewards[index];
            if ((~livenessReceiveFlag & (1 << index)) != 0) {  // 判断领取标志位
                if(liveness.liveness >= template.liveness){
                    // 设置领取标志
                    livenessReceiveFlag |= 1 << index;

                    if(template.silver > 0){
                        human.increaseSilver(template.silver, Consts.SOUL_CHANGE_LOG_TYPE_CONTSIGN_LIVENESS_REWARD, index, true);
                    }
                    if(template.gold > 0){
                        human.increaseGold(0, template.gold, Consts.SOUL_CHANGE_LOG_TYPE_CONTSIGN_LIVENESS_REWARD, index, true);
                    }
                    if(template.energy > 0){
                        human.increaseEnergy(template.energy, true);
                    }

                    human.sendMessage(ClientToMapBuilder.buildReceiveLivenessReward(index));

                    // 记录行为日志
                    if (MapConfig.INSTANCE.useCYLog == true) {
                        List<String> cyLogList = new ArrayList<String>();
                        cyLogList.add("behaviorMC");
                        cyLogList.add(String.valueOf(MapConfig.INSTANCE.gameId));
                        cyLogList.add("KDTY");
                        cyLogList.add(String.valueOf(human.id));
                        cyLogList.add(human.name);
                        cyLogList.add("");
                        cyLogList.add("LivenessRewardDBBehavior");
                        cyLogList.add(index + " ");
                        cyLogList.add("");
                        cyLogList.add("");
                        cyLogList.add("");
                        cyLogList.add("");
                        cyLogList.add("");
                        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileCYGameLogMessage(cyLogList, GameLogMessage.GameLogType.GAMELOGTYPE_CY_BEHAVIOR));
                    }
                    GameLogger.getlogger().log(GameLogMessageBuilder.buildLivenessRewardDBBehaviorGameLogMessage(human.id, index));
                } else {
                     GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                                "human [" + human.id + "] can't receive livenss reward because liveness isn't enough"));
                }
            } else {
                 GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                            FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                            "human [" + human.id + "] can't receive livenss reward because of has received"));
            }
        }
    }

    public void sign(boolean needSend){
        int curDay = (int) ((GameServer.INSTANCE.getCurrentTime() + Consts.JET_LAG) / Consts.MILSECOND_ONE_DAY);
        if(curDay > lastOnlineDay){ // 判断是否今天第一次登陆
            // 重置活跃度
            liveness = new Liveness(human);
            // 清除活跃度领取标志
            livenessReceiveFlag = 0;

            // 增加累计登陆天数
            if (cumulativeNum < ContSignTemplates.INSTANCE.cumulativeRewards.length) {
                cumulativeNum++;        // 累计登陆天数
                cumulativeRewardNum++;  // 当前可领奖天数
            }

            if(curDay > lastOnlineDay + 1){
                // 清除连续登陆
                consecutiveNum = 1;
                consecutiveReceiveFlag = 0;
            } else {
                consecutiveNum++;
                if (consecutiveNum > ContSignTemplates.INSTANCE.consecutiveRewards.length) {
                    consecutiveNum = ContSignTemplates.INSTANCE.consecutiveRewards.length;
                    consecutiveReceiveFlag = consecutiveReceiveFlag & ~(1 << (consecutiveNum-1));   // 将最后一天的领取标志设置为未领取
                }
            }
            
            lastOnlineDay = curDay;
        }
        if(needSend){
            human.sendMessage(ClientToMapBuilder.buildContSign(buildContSignProto()));
        }
    }

}
